﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZXing;
using ZXing.QrCode;

namespace CardMonitor.Utils
{
    public class QRcodeUtils
    {
        public static byte[] CreateQRCode(string data, int height = 100
                        , int width = 100, int margin = 0)
        {
            byte[] bytes = null;
            var barcodeWriter = new ZXing.BarcodeWriter()
            {
                Format = ZXing.BarcodeFormat.QR_CODE,
                Options = new ZXing.QrCode.QrCodeEncodingOptions()
                {
                    Height = height,
                    Width = width,
                    Margin = margin
                }
            };
            using (var image = barcodeWriter.Write(data))
            {
                using (var stream = new System.IO.MemoryStream())
                {
                    image.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                    bytes = stream.ToArray();
                }
            }
            return bytes;
        }

        /// <summary>
        /// Converts a QR code and decodes it to its string data 
        /// </summary>
        /// <param name="bytes">The QR code byte array</param> 
        /// <returns>The string data decoded from the QR code</returns>
        public static string ReadQRCode(byte[] bytes)
        {
            var result = string.Empty;
            using (var stream = new System.IO.MemoryStream(bytes))
            {
                using (var image = System.Drawing.Image.FromStream(stream))
                {
                    var barcodeReader = new ZXing.BarcodeReader();
                    var decoded = barcodeReader.Decode((System.Drawing.Bitmap)image);
                    if (decoded != null)
                    {
                        result = decoded.Text;
                    }
                }
            }
            return result;
        }

        public static Bitmap createQRImage(string str)
        {
            QrCodeEncodingOptions options = new QrCodeEncodingOptions();
            options.CharacterSet = "UTF-8";
            options.DisableECI = true; // Extended Channel Interpretation (ECI) 主要用于特殊的字符集。并不是所有的扫描器都支持这种编码。
            options.ErrorCorrection = ZXing.QrCode.Internal.ErrorCorrectionLevel.H; // 纠错级别
            options.Width = 300;
            options.Height = 300;
            options.Margin = 1;
            BarcodeWriter writer = new BarcodeWriter();
            writer.Format = BarcodeFormat.QR_CODE;
            writer.Options = options;

            Bitmap bmp = writer.Write(str);
            return bmp;
        }

        /// <summary>
        /// 识别二维码
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        public static string readCode(Bitmap bmp)
        {
            string str = "";
            BarcodeReader reader = new BarcodeReader();
            reader.Options.CharacterSet = "UTF-8";
            try
            {
                Result result = reader.Decode(bmp);
                if (result != null)
                {
                    str = result.Text;
                }
            }
            catch (Exception)
            {
                return str;
            }

            return str;
        }

        /// <summary>
        /// 识别二维码
        /// </summary>
        /// <param name="imagePath"></param>
        /// <returns></returns>
        public static string readCode(string imagePath)
        {
            string str = "";
            BarcodeReader reader = new BarcodeReader();
            reader.Options.CharacterSet = "UTF-8";
            using (Bitmap bmp = new Bitmap(imagePath))
            {
                try
                {
                    Result result = reader.Decode(bmp);
                    if (result != null)
                    {
                        str = result.Text;
                    }
                }
                catch (Exception)
                {
                    return str;
                }
            }

            return str;
        }
    
}
}
